//                            _ooOoo_  
//                           o8888888o  
//                           88" . "88  
//                           (| -_- |)  
//                            O\ = /O  
//                        ____/`---'\____  
//                      .   ' \\| |// `.  
//                       / \\||| : |||// \  
//                     / _||||| -:- |||||- \  
//                       | | \\\ - /// | |  
//                     | \_| ''\---/'' | |  
//                      \ .-\__ `-` ___/-. /  
//                   ___`. .' /--.--\ `. . __  
//                ."" '< `.___\_<|>_/___.' >'"".  
//               | | : `- \`.;`\ _ /`;.`/ - ` : | |  
//                 \ \ `-. \_ __\ /__ _/ .-` / /  
//         ======`-.____`-.___\_____/___.-`____.-'======  
//                            `=---='  
//  
//         .............................................  
//                  佛祖保佑             永无BUG 
//          佛曰:  
//                  写字楼里写字间，写字间里程序员；  
//                  程序人员写程序，又拿程序换酒钱。  
//                  酒醒只在网上坐，酒醉还来网下眠；  
//                  酒醉酒醒日复日，网上网下年复年。  
//                  但愿老死电脑间，不愿鞠躬老板前；  
//                  奔驰宝马贵者趣，公交自行程序员。  
//                  别人笑我忒疯癫，我笑自己命太贱；  
//                  不见满街漂亮妹，哪个归得程序员？  


/* ****************************************************************************
 * Author: 671643387
 * Date: 2015/6/4
 * ***************************************************************************/

///////////////////////////////////////////////////////////////////////////////
// 好友系统-平乱

function Insurgency() {
    this.insurgency = {};

    this.updates = {};
    this.dirtyCount = 0;
}

Insurgency.create = function(){
    gDBWorld.insert({_id:"insurgency", insurgency:{}}, function(err, result){});
};


Insurgency.prototype = {

    init: function(fn){
        // 读取平乱数据
        gDBWorld.findOne({_id : 'insurgency'}, {}, function(err, doc){
            if( doc ) {
                this.insurgency = doc.insurgency;
            }
            fn();
        }.bind(this));
    },

    markDirty: function(uid, data){
        this.updates[util.format('insurgency.%d', uid)] = data;
        this.dirtyCount++;
    },

    save: function(force, fn){
        if (!force && (this.dirtyCount < 1)) {
            fn && fn(true);
        } else {
            var updates = this.updates;
            this.updates = {};
            this.dirtyCount = 0;

            gDBWorld.update({_id : 'insurgency'}, {$set:updates}, true, function(err, result){
                if( err ) {
                    ERROR(util.format('SAVE INSURGENCY: %j %j', updates, err));
                    fn && fn(false);
                }else {
                    LOG(util.format('SAVE INSURGENCY: %j', updates));
                    fn && fn(true);
                }
            });
        }
    },

    /**
     * 触发平乱事件
     * @param player
     * @param uid
     */
    triggerEvent: function(player, uid) {
        var userInsurgency = this._getInsurgencyByUid(uid);

        if (userInsurgency.sign == 1) {
            return;
        }

        userInsurgency.sign = 1;    // 标记为可以平乱
        userInsurgency.blocks = {}; // 清空不可帮助平乱的好友列表
        userInsurgency.time = Date.getStamp();  // 更新时间戳

        // 更新保存数据
        this.insurgency[uid] = userInsurgency;
        this.markDirty(uid, userInsurgency);
        this.save();
    },

    /**
     * 获取指定UID的平乱数据
     * @param uid
     * @returns {*}
     */
    getByUid: function(uid) {
        return this._getInsurgencyByUid(uid);
    },

    /**
     *
     * @param myUid
     * @param fUid
     * @returns {0:不可见,1:可见}
     */
    getFriendSignByUid: function(myUid, fUid) {

        var uInsurgency = this._getInsurgencyByUid(myUid);
        var fInsurgency = this._getInsurgencyByUid(fUid);

        // 判断帮助平乱次数是否达到限制
        if (uInsurgency.count >= +gConfGlobal.InsurgencyDailyTimes) {
            return 0;
        }

        // 判断玩家是否被屏蔽
        if (fInsurgency.blocks && (myUid in fInsurgency.blocks)) {
            return 0;
        }
        return fInsurgency.sign;
    },

    /**
     * 获取玩家平乱数据，跨天会自动重置
     * @param uid
     * @returns {*}
     * @private
     */
    _getInsurgencyByUid: function(uid) {
        var _uInsurgency = this.insurgency[uid] || {
                sign: 0,    // 可见标志
                count: 0,   // 玩家今天的帮助平乱次数
                time: 0,    // 平乱开始时间戳
                blocks: {}  // 屏蔽的好友
            };

        if (Date.getDayPassed(_uInsurgency.time) != 1) {  // 跨天，更新数据
            _uInsurgency = {
                sign: 0,
                count: 0,
                time: Date.getStamp(),
                blocks: {}
            };
            this.insurgency[uid] = _uInsurgency;
            this.markDirty(uid, _uInsurgency);
            this.save();
        }

        return _uInsurgency;
    },

    /**
     * 把当前玩家加入好友的平乱屏蔽列表
     * @param myUid 当前玩家UID
     * @param fUid  好友UID
     */
    blockUser: function(myUid, fUid) {
        var fInsurgency = this._getInsurgencyByUid(fUid);
        var fBlocks = fInsurgency.blocks;
        fBlocks[myUid] = 1;
        fInsurgency.blocks = fBlocks;

        // 更新保存数据
        this.insurgency[fUid] = fInsurgency;
        this.markDirty(fUid, fInsurgency);
        this.save();
    },

    /**
     * 平乱打怪
     * @param player
     * @param fUid
     * @param fn
     */
    battle: function(player, fUid, fn){
        var ret = {};

        var uInsurgency = this._getInsurgencyByUid(player.uid); // 获取当前玩家平乱数据
        var fInsurgency = this._getInsurgencyByUid(fUid);   // 获取好友平乱数据

        // 达到每日平乱上限
        if (uInsurgency.count >= +gConfGlobal.InsurgencyDailyTimes) {
            fn("time reach top");
            return;
        }

        // 判断玩家是否被屏蔽
        if (player.uid in fInsurgency.blocks) {
            fn("you are blocked");
            return;
        }

        // 检查是否是好友
        if (!gFriend.isFriend(fUid, player.uid)) {
            fn("you are not friends");
            return;
        }

        // 检查好友是否可以帮助
        if (fInsurgency.sign != 1) {
            fn("monster killed or can not help");
            return;
        }

        player.roleImageInit();

        // 计算怪物血量
        var factor = +gConfGlobal.InsurgencyMonsterFactor / 100;// 计算怪物初始血量
        var monsterHealth = Math.floor(player.getRoleImageAttrCount("health") * factor);

        var attacker = new Fighter();
        var defender = new Fighter();
        attacker.initWithPlayer(player);
        defender.initWithInsurgencyMonster(player, {
            init_health: monsterHealth,     // 怪物初始血量
            health: monsterHealth,          // 怪物总血量
        }, roundIds(gConfInsurgencyTeam, 1)[0]);

        var battleReport = attacker.fight(defender);
        var defRemainInfo = battleReport.def_remain_info;

        ret.battle = battleReport;

        // 计算怪物剩余血量
        var defRemainHealth = 0;
        for (var rid in defRemainInfo) {
            defRemainHealth += defRemainInfo[rid].health;
        }

        // 更新好友的平乱数据
        if (defRemainHealth <= 0) { // 怪物被干死了，本次事件完成
            fInsurgency.sign = 0;
            fInsurgency.blocks = {};
        }

        // 返回怪物剩余血量
        ret.health = defRemainHealth;

        // 保存好友平乱数据
        this.insurgency[fUid] = fInsurgency;
        this.markDirty(fUid, fInsurgency);
        this.save();

        fn(null, ret);
    }
};

exports.Insurgency = Insurgency;